package com.docMan.utils;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.struts2.ServletActionContext;
import org.omg.CORBA.PUBLIC_MEMBER;

import com.google.gson.Gson;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfStructTreeController.returnType;
import com.itextpdf.text.pdf.PdfWriter;

public class ProjectUtils {
	public static Gson gson=new Gson();
	
	public static String getImgClass(String path) {
		String type = path.substring(path.lastIndexOf(".") + 1, path.length());
		switch (type) {
		case "doc":
			return "file_word_ico_d32";
		case "docx":
			return "file_word_ico_d32";
		case "xls":
			return "file_excel_ico_d32";
		case "jpg":
			return "file_photo_ico_d32";
		case "png":
			return "file_photo_ico_d32";
		case "pdf":
			return "file_pdf_ico_d32";
		case "txt":
			return "file_txt_ico_d32";
		default:
			return "file_chm_ico_d32";
		}
	}
	/**
	 * 获取web项目的绝对路径
	 * @return
	 */
	@SuppressWarnings("deprecation")
	public static String getProject(String path){
		return ServletActionContext.getRequest().getRealPath("/")+path;
	}
	/**
	 *  获取文件个编码格式 gbk utf-8等
	 * @param fileName 文件的路径
	 * @return
	 * @throws Exception
	 */
	public static String codeString(String fileName) throws Exception{  
	    BufferedInputStream bin = new BufferedInputStream(  
	    new FileInputStream(fileName));  
	    int p = (bin.read() << 8) + bin.read();  
	    String code = null;  
	      
	    switch (p) {  
	        case 0xefbb:  
	            code = "UTF-8";  
	            break;  
	        case 0xfffe:  
	            code = "Unicode";  
	            break;  
	        case 0xfeff:  
	            code = "UTF-16BE";  
	            break;  
	        default:  
	            code = "GBK";  
	    }  
	      
	    return code;  
	}  
	/**
	 * 获取文件的类型
	 * @param fileName 可以是文件名或者文件的路径
	 * @return
	 */
	public static String getFileType(String fileName){
		String type =fileName.substring(fileName.lastIndexOf(".")+1, fileName.length());
		return type;
	}
	public static double fomartDecmial(double data){
		DecimalFormat df= new DecimalFormat("#0.0");
		return Double.parseDouble(df.format(data));
	}
	public static String timeStamp2String(Timestamp timestamp){
		DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm");
		return dateFormat.format(timestamp);
	}
	
	/**
	 * 格式化时间
	 * @param format
	 * @param date
	 * @return
	 */
	public static String date2String(String format,Date date){
		SimpleDateFormat sim=new SimpleDateFormat(format);
		return  sim.format(date);
	}
	public static String getHql(String head,Map<String, String> params){
		int countNotNull=0;
		for (String param : params.keySet()) {
			if (!params.get(param).equals("")&&params.get(param)!=null&&Integer.parseInt(params.get(param)+"")!=0) {
				countNotNull++;
			}
			if(params.get(param)==null||params.get(param).equals("")){
				params.put(param, "0");
			}
		}
		int count=0; 
		for (String param : params.keySet()) {
			if (Integer.parseInt(params.get(param))!=0) {
				if(count==0)
					head+="where ";
				if(countNotNull>=1 &&count!=countNotNull-1){
					head+=param+"=? and ";
				}else{
					head+=param+"=? ";
				}
				count++;
			}
		}
		return head;
	}
	/**
	 * 获取格式化的当前时间
	 * @param fmt 格式华字符串
	 * @return
	 */
	public  static Date getDate(String fmt) {
		 SimpleDateFormat simpleDateFormat=new SimpleDateFormat(fmt);
		 
		 Date date=null;
		 try {
			date=simpleDateFormat.parse(simpleDateFormat.format(new Date()));
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return date;
	}
	
	public static java.sql.Date getDateSql(String fmt,String dateStr){
		SimpleDateFormat simpleDateFormat=new SimpleDateFormat(fmt);
		 
		 Date date=null;
		 java.sql.Date dates=null;
		 try {
			date=simpleDateFormat.parse(dateStr);
			dates=new java.sql.Date(date.getTime());
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return dates;
	}
	
	/**
	 * 通过反射 从page 类中 获取sql 查询语句
	 * @param page 封装了查询参数的page类
	 * @param header 查询语句的前半部分 例如 select a from A a where 
	 * @param table 持久化对象的名字 的别名 例如 a 【要在a前加一个空格】 
	 * @return
	 */
	public static String getHqlByReflect(Object page,String header,String table){
		String hql=header;
		boolean isOrder=false;
		String orderByName="";
		List<String> list=getClassPropertyName(page);
		//list.addAll(getClassPropertyNameF(page));
		for (String string : list) {
			Object value=getter(page, string);
			 if(value!=null&&!string.equals("params")&&value!=""&&!string.equals("paramsOrder")){
				 if(string.equals("orderBy")){
					 orderByName=string;
					 isOrder=true;
				 }else{
					 hql+=  table+string+" like  ?  and";
				 }
				 
			 }
		}
		if(hql.endsWith("where ")){
			return hql.replace("where", "");
		}
		if(hql.endsWith("and")){
			hql=hql.substring(0,hql.lastIndexOf("and")-1);
		}
		if(isOrder){
			hql+="order by"+table+getter(page, orderByName);
			
		}
		return hql;
	}
	
	/**
	 * 通用的将对象相同属性进行复制转换
	 *  @param objTo 目标对象
     * @param objFrom 被复制对象
	 * @return
	 */
	public static Object objAdapterObjGeneral(Object objTo,Object objFrom){
		Class<?> clazzTo=getClassReverberate(objTo);
		Field[] fieldsTo=clazzTo.getDeclaredFields();
		Class<?> clazzFrom=getClassReverberate(objFrom);
		Field[] fieldsFrom=clazzFrom.getDeclaredFields();
		for (int i = 0; i < fieldsTo.length; i++) {
			for (int j = 0; j < fieldsFrom.length; j++) {
				if(fieldsTo[i].getName().equals(fieldsFrom[j].getName())&&getter(objFrom, fieldsFrom[j].getName())!=null){
					setter(objTo, fieldsTo[i].getName(), getter(objFrom, fieldsFrom[j].getName()), fieldsTo[i].getType());
				}
			}
		}
		
		return objTo;
		
	}
	
	
    /**
     * 该方法只是用于分页对象page之间的转换
     * 对象的转换，将属性名字相同的值复制到objTo中去
     * 并将查询参数和参数的顺序保存到 Page<T>的params和paramsOrder 中去
     * String 类型的参数都带%% 其它类型 不带%%
     * @param objTo 目标对象
     * @param objFrom 被复制对象
     * @return
     */
    public static Object objAdapterObj(Object objTo,Object  objFrom){
    	Class<?> clazzTo = getClassReverberate(objTo);
    	Field[] fieldsTo=clazzTo.getDeclaredFields();
    	Class<?> clazzFrom=getClassReverberate(objFrom);
    	Field[] fieldsFromParents=clazzFrom.getSuperclass().getDeclaredFields();
    	List<String> paramsOrder=new ArrayList<String>();
    	for(int i=0;i<fieldsTo.length;i++){
    		for (int j = 0; j < fieldsFromParents.length; j++) {
				if(fieldsTo[i].getName().equals(fieldsFromParents[j].getName())){
					setter(objTo, fieldsTo[i].getName(),getter(objFrom,fieldsFromParents[j].getName()), fieldsTo[i].getType());
				}
			}
    	}
    	
    	Map<String, Object> params=new HashMap<String, Object>();
    	Field[] fieldsFrom=clazzFrom.getDeclaredFields();
    	for (int i = 0; i <fieldsFrom.length; i++) {
    		if(getter(objFrom, fieldsFrom[i].getName())!=null&&getter(objFrom, fieldsFrom[i].getName())!=""
    				){
    			//params和orderBy不用加到参数中去
    			if(!fieldsFrom[i].getName().equals("params")&&!fieldsFrom[i].getName().equals("orderBy")){
    				System.out.println(fieldsFrom[i].getType().getName());
    				if(fieldsFrom[i].getType().getName().equals("java.lang.String")){
    					//String 类型的都是用 like，并且不是orderBy 的参数
    					if(!fieldsFrom[i].getName().equals("orderBy")){
    						params.put(fieldsFrom[i].getName(), "%"+getter(objFrom, fieldsFrom[i].getName()).toString().replace("%", "")+"%");
						}
    					
    				}else{
    					//其他类型 用=来组成sql 语句 既参数值是不带%%的
    					params.put(fieldsFrom[i].getName(), getter(objFrom, fieldsFrom[i].getName()));
    				}
    				paramsOrder.add(fieldsFrom[i].getName());
    			}
    		}
		}
    	for (int i = 0; i < fieldsTo.length; i++) {
			if(fieldsTo[i].getName().equals("params")){
				System.out.println(fieldsTo[i].getType());
				setter(objTo, "params", params, fieldsTo[i].getType());
			}
			if(fieldsTo[i].getName().equals("paramsOrder")){
				setter(objTo, "paramsOrder", paramsOrder, fieldsTo[i].getType());
			}
		}
    	return objTo;
    }
    
    /**
     * 返回所有类的名字
     * @param tables
     * @return List<String>
     */
    public List<String> getClassNames(List<?> tables){
        List<String> classNames = null;
        if(tables != null && tables.size()!=0){
            classNames = new ArrayList<String>();
            for(Object obj : tables){
                classNames.add(obj.getClass().getSimpleName());
            }
        }
        return classNames;
    }
    
    /**
     * 返回类的名字
     * @param table
     * @return
     */
    public static String getClassName(Object table){
        String className = null;
        if(table != null){
            className=table.getClass().getSimpleName();
        }
        return className;
    }
    
    
    /**
     * 给传入的对象做反射
     * @param o
     * @return
     */
    public static Class<?> getClassReverberate(Object o){
        String ClassName = o.getClass().getName();
        Class<?> demo = null;
        try {
            demo = Class.forName(ClassName);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return demo;
    }
    
    /**
     * 返回类中的所有属性
     * @param o
     * @return List<String>
     */
    public static List<String> getClassPropertyName(Object o) {
        Class<?> demo = getClassReverberate(o);
        List<String> classPropertyNames = null;
        Field[] field = demo.getDeclaredFields();
        classPropertyNames = new ArrayList<String>();
        for (int i = 0; i < field.length; i++) {
            classPropertyNames.add(field[i].getName());
        }
        return classPropertyNames;
    }
    /**
     * 获取对象 O的父类的所有属性名
     * @param o
     * @return
     */
    public static List<String> getClassPropertyNameF(Object o) {
        Class<?> demo = getClassReverberate(o);
        
        List<String> classPropertyNames = null;
        Field[] field = demo.getSuperclass().getDeclaredFields();
        classPropertyNames = new ArrayList<String>();
        
        for (int i = 0; i < field.length; i++) {
            classPropertyNames.add(field[i].getName());
        }
        return classPropertyNames;
    }
    /**
     * 使用反射调用对象的get方法
     * @param obj
     *            操作的对象
     * @param att
     *            操作的属性
     * */
    public static Object getter(Object obj, String att) {
        try {
            Method method = obj.getClass().getMethod("get" + firstLower(att));
            return method.invoke(obj);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
 
    /**
     * 使用反射调用对象的set方法
     * @param obj
     *            操作的对象
     * @param att
     *            操作的属性
     * @param value
     *            设置的值
     * @param type
     *            参数的属性
     * */
    public static void setter(Object obj, String att, Object value,
            Class<?> type) {
        try {
            Method method = obj.getClass().getMethod("set" + firstLower(att), type);
            method.invoke(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    /**
     * 给setter()的操作的属性首字母大写
     * @param att setter()操作的属性
     * @return 
     */
    protected static String firstLower(String att) {
        StringBuffer sb = new StringBuffer();
        sb.append(att.substring(0,1).toUpperCase());
        sb.append(att.substring(1, att.length()));
        return sb.toString();
    }
	
    /**
     * 根据hql语句获得memcached 的key
     * memcached的key不能有空格
     * @param hql
     * @return
     */
    public static String getMemcachedKey(String hql){
    	return hql.hashCode()+"";
    }
    /**
     * 根据hql和参数值 hash得到memcached的key
     * @param hql
     * @param objects
     * @return
     */
    public static String getMemcachedKey(String hql,Object...objects){
    	String key="";
    	for (Object object : objects) {
			hql+=object.toString();
		}
    	key+=hql.hashCode();
    	return key;
    }
	/**
	 * 返回行数的键
	 * @param hql
	 * @param objects
	 * @return
	 */
    public static String getRowCountKey(String hql,Object...objects){
    	String keyString="count_"+hql;
    	for (Object object : objects) {
			keyString+=object.hashCode();
		}
    	return keyString;
    }
    
    public static String getSysDate(String format){
    	SimpleDateFormat simpleDateFormat=new SimpleDateFormat(format);
    	
    	return simpleDateFormat.format(new Date());
    }
    /**
     * 删除list下所有元素是null的
     * @param list
     */
    public static List<?> removeListNull(List<?> list){
    	ArrayList<?> nullArr=new ArrayList<Object>();
    	nullArr.add(null);
    	list.removeAll(nullArr);
    	return list;
    }
    
    public static Object setObjDateFormat(Object obj,String dateFormat){
    	 Class<?> demo = getClassReverberate(obj);
    	 Field[] fields=demo.getDeclaredFields();
    	 for (Field field : fields) {
			if(field.getType()==Date.class){
				DateFormatUtils.format((Date)getter(obj, field.getName()),dateFormat);
			}
		}
    	return ""; 
    }
    /**
     * 将图片转换成pdf
     * @param oldPath 源文件的图片路径
     * @param newPath 要保存的pdf路径
     * @return
     */
    public static boolean image2Pdf(String oldPath,String newPath){
		Document doc = new Document(PageSize.A3, 20, 20, 20, 20); 
        try { 
            PdfWriter 
                    .getInstance(doc, new FileOutputStream(newPath)); 
            doc.open(); 
                doc.newPage(); 
                doc.add(new Paragraph("简单使用iText")); 
                Image png1 = Image.getInstance(oldPath); 
                float heigth = png1.getHeight(); 
                float width = png1.getWidth(); 
                int percent = getPercent(heigth, width); 
                png1.setAlignment(Image.MIDDLE); 
                png1.scalePercent(percent+3);// 表示是原来图像的比例; 
                doc.add(png1); 
            doc.close(); 
        } catch (FileNotFoundException e) { 
            e.printStackTrace(); 
        } catch (DocumentException e) { 
            e.printStackTrace(); 
        } catch (IOException e) { 
            e.printStackTrace(); 
        } 
   
        File mOutputPdfFile = new File(newPath); 
        if (!mOutputPdfFile.exists()) { 
            mOutputPdfFile.deleteOnExit(); 
            return false; 
        } 
		return true; 
	}
    /**
     * 第一种解决方案 在不改变图片形状的同时，判断，如果h>w，则按h压缩，否则在w>h或w=h的情况下，按宽度压缩
     *
     * @param h
     * @param w
     * @return
     */ 
   
    public static int getPercent(float h, float w) { 
        int p = 0; 
        float p2 = 0.0f; 
        if (h > w) { 
            p2 = 297 / h * 120; 
        } else { 
            p2 = 420 / w * 120; 
        } 
        p = Math.round(p2); 
        return p; 
    } 
    
    /**
     * 第二种解决方案，统一按照宽度压缩 这样来的效果是，所有图片的宽度是相等的，自我认为给客户的效果是最好的
     *
     * @param args
     */ 
    public static int getPercent2(float h, float w) { 
        int p = 0; 
        float p2 = 0.0f; 
        p2 = 530 / w * 100; 
        p = Math.round(p2); 
        return p; 
    } 
    /**
     * 删除指定路劲的文件
     * @param filepath
     * @throws Exception
     */
    public static void deleteFile(String filepath) throws Exception{
    	File file=new File(filepath);
    	file.delete();
    }
    
    public static int getYear(Date date){
    	Calendar calendar=Calendar.getInstance();
    	calendar.setTime(date);
    	return calendar.get(Calendar.YEAR);
    	
    }
    
    
}
